(function(vita, location, window){
    /****
     * end和assist的返回值说明
     *
     * 返回值：数组
     * 第一个元素：目标node的名称，同组件名，类型——字符串或者数组，如果是数组，第一个元素是node名称，第二个元素是入参，类型是对象，
     *          key是入参名，value是入参值（第二个入参可无），第三个元素，类型是布尔值，true时表示需要刷新，当没有上述的入参（第二个元素）时，
     *          该元素将作为第二个元素
     * 第二个元素：回调函数，类型——函数或者数组，如果是数组，第一个元素是函数，第二个元素是上下文对象（可无）
     *
     * 补充：（1）第一个元素，目标node名称后，加":open"，可以使用open或者自定义方式打开，参数为openMethod
     *       (2) 第一个元素，目标node名称后，加":menu"，可以指定容器展示
     *      （3）参数timeout，设定加载超时时间，默认60000毫秒
     * ***/
    vita.widget("webAssist",{
        /**全局缓存**/
        global : {
            prototypes : {},//原型管理
            assists : {},//流程节点管理
            assistElements : {}//流程界面元素管理
        },
        /**组件销毁**/
        _destroy : function(){
            //还原原型，并清除原型缓存
            var prototypes = this.global.prototypes;
            $.each(prototypes, function(key, pt){
                var prototype = eval(key);
                prototype.end = pt.oEnd;
                prototype.assist = pt.oAssist;
                delete prototype.flowing;
            });
            delete this.global.prototypes;
            //清除流程节点缓存
            delete this.global.assists;
            //清除流程界面元素缓存//TODO 是否要销毁所有组件？
            delete this.global.assistElements;
        },
        /**增加流程**/
        add : function(assist){
            this._initPrototype(assist);
            this._initElement(assist);
            this._initAssist(assist);
            return this._getAssistElement(assist.assistName);
        },
        /**初始化原型**/
        _initPrototype : function(assist){
            var widget = this, global = widget.global, prototype = eval(assist.prototype);
            //判断原型是否为对象
            if($.type(prototype) != "object"){
                throw new Error("创建流程失败，指定的prototype(" + assist.prototype + ")不是对象！");
            }
            //判断在指定原型里是否已经创建了流程
            if(!prototype.flowing){
                //保存原型原有的end和assist方法
                global.prototypes[assist.prototype] = {
                    oEnd : prototype.end,
                    oAssist : prototype.assist
                };
                //扩展原型
                $.extend(prototype,{
                    flowing : true,
                    end : function(){
                        var args = [this];
                        widget._end.apply(widget, args.concat(Array.prototype.slice.call(arguments)));
                    },
                    assist : function(){
                        var args = [this];
                        widget._assist.apply(widget, args.concat(Array.prototype.slice.call(arguments)));
                    }
                });
            }
        },
        /**初始化流程节点**/
        _initAssist : function(assist){
            var widget = this, oNodes = assist.nodes, global = widget.global,
                ass = global.assists[assist.assistName] = {
                    prototype : assist.prototype,
                    nodes : {},
                    callBackStack : {},
                    openMethod : assist.openMethod ? assist.openMethod : "open",
                    timeout : assist.timeout ? assist.timeout : 60000,
                    mask : typeof assist.mask === "undefined" ? true : !!assist.mask,
                    plural : !!assist.plural,
                    headers : typeof assist.headers === "undefined" ? null : assist.headers
                }, gNodes = ass.nodes;
            if($.isArray(oNodes) && oNodes.length > 0){
                $.each(oNodes,function(oIndex,node){
                    gNodes[node.name] = node;
                    if(oIndex == 0){
                        ass.firstNode = node;
                    }
                    if(node.name == assist.appointedNode){
                        ass.firstNode = widget.getNode(assist.assistName, assist.appointedNode);
                    }
                });
            }
            //导航到指定节点，否则导航到第一个节点
            var goNode = ass.firstNode;
            goNode.params = assist.params;
            if(goNode.mode == "back-end"){
                widget._forBackEnd(assist.assistName, goNode);
            }else {
                widget.navigate(assist.assistName, goNode.name);
            }
        },
        //从服务获取界面
        _forBackEnd : function (assistName, node) {
            var widget = this, global = this.global, assist = global.assists[assistName];
            vita.ajax(node.url, widget._dealParams($.extend({inFrame : true}, node.params)), function (re) {
                if(re.indexOf("end") == 0){
                    //当前流程结束，操作权交还上级流程
                    var param = re.split("|")[1], e = widget._getAssistElement(assistName);
                    if(!e.parent().is("body")){
                        //如果不是顶级，交还上级
                        if(e && vita.self("isFunction", e.assemble)){
                            e.assemble("end", "end", param);
                        }
                    }else {
                        //如果是顶级，交还本节点
                        var tNode = widget.getNode(assistName, node.name);
                        var nextTar = tNode.end("end", param);
                        widget._toNextTarget(assistName, nextTar, null);
                    }
                }else {
                    var name = $(re).filter("[data-widget]:first").attr("data-widget"), element = widget._getAssistElement(assistName),
                        div = widget._getNodeElement(assistName, name);
                    if(div.length == 0){
                        div = widget._newNodeElement(assistName, name).appendTo(element);
                    }
                    div.html(re);
                    if(!assist.nodes[name]){
                        assist.nodes[name] = {
                            name : name
                        };
                    }
                    widget.navigate(assistName, name);
                }
            }, {mask : assist.mask, timeout : assist.timeout});
        },
        /**初始化流程界面元素**/
        _initElement : function(assist){
            var assistName = assist.assistName, elements = this.global.assistElements[assistName],
                div = $("<div/>").attr({"data-widget":"assemble", "data-assistName":assistName}).css("height", "100%");
            if(!elements){
                elements = this.global.assistElements[assistName] = [];
            }
            if(assist.plural){
                elements.unshift(div);
            }else{
                elements[0] = div;
            }
        },
        /**通过流程名称获取流程元素**/
        _getAssistElement : function (assistName, parent) {
            var re = this.global.assistElements[assistName][0];
            if(parent && parent > 0){
                re = re.parents("div[data-assistName]:eq(" + (parent - 1) + ")");
            }
            return re;
        },
        //切换流程实例
        rotateAssist : function (assistName, vitaId) {
            var re = this.global.assistElements[assistName];
            if(re && re.length > 0){
                var tar = re[0].parent(), newArr = [], tarWidget;
                re[0].detach();
                for(var a in re){
                    tarWidget = re[a].find("[data-vid="+vitaId+"]");
                    if(tarWidget.length == 1){
                        tar.append(re[a]);
                        newArr.unshift(re[a]);
                        if(tarWidget.parent().is("[data-assist]")){
                            tarWidget.parent().show();
                        }else {
                            tarWidget.parentsUntil("[data-assist]").parent().show();
                        }
                    }else {
                        newArr.push(re[a]);
                    }
                }
                this.global.assistElements[assistName] = newArr;
                var nodes = newArr[0].children(), tNode;
                nodes.each(function (index, node) {
                    tNode = $(node);
                    if(tNode.css("display") != "none"){
                        return false;
                    }
                });
                this.navigate(assistName, tNode.attr("data-assist"));
            }
        },
        //释放流程实例
        destroyAssist : function (assistName, vitaId) {
            var re = this.global.assistElements[assistName], container;
            if(re && re.length > 0){
                var newArr = [], cur;
                for(var a in re){
                    if(re[a].find("[data-vid="+vitaId+"]").length == 1){
                        cur = re[a];
                        if(a == 0){
                            //如果删除的是当前的实例，要保留下容器，并在之后自动加载下一个实例，不然后面切换的时候会找不到容器
                            container = cur.parent();
                        }
                    }else {
                        newArr.push(re[a]);
                    }
                }
                container && container.append(newArr[0]);
                this.global.assistElements[assistName] = newArr;
                //释放流程实例
                if(cur){
                    var widgets = cur.find("[data-vid]");
                    widgets.each(function(i, w){
                        var ww = $(w), name = ww.attr("data-widgetfullname").split("-")[1];
                        if($.isFunction(ww[name])){
                            ww[name]("destroy");
                        }
                    });
                    cur.remove();
                }
            }
        },
        /**通过流程名称和节点名称获取节点元素**/
        _getNodeElement : function (assistName, nodeName) {
            return this._getAssistElement(assistName).find("[data-assist="+nodeName+"][data-adhere="+assistName+"]");
        },
        /**创建流程节点**/
        _newNodeElement : function (assistName, nodeName) {
            return $("<div/>").attr({"data-assist":nodeName,"data-adhere":assistName}).css("height", "100%");
        },
        /**获取当前节点所在的流程名称**/
        _getAssistName : function(tarElement){
            return tarElement.closest("[data-assist]").attr("data-adhere");
        },
        /**获取流程设置**/
        _getAssist : function (assistName) {
            return this.global.assists[assistName];
        },
        /**判断是否属于子流程**/
        _isChildrenAssist : function (parent, children) {
            return !!this._getNodeElement(parent, children).children("[data-assistname="+children+"]").length;
        },
        /**end实现**/
        _end : function(){
            var widget = this, tarWidget = arguments[0], nextTar,
                args = Array.prototype.slice.call(arguments,1), assistName = widget._getAssistName(tarWidget.getElement());
            //如果有回调函数，只执行回调函数
            var assist = widget._getAssist(assistName), selfCallBack = assist.callBackStack[tarWidget.getWidgetName()], redirect = args[args.length-1];
            if(selfCallBack && redirect != vita.REDIRECT){
                if(vita.self("isObject",selfCallBack[1])){
                    nextTar = selfCallBack[0].apply(selfCallBack[1], args);
                }else{
                    nextTar = selfCallBack[0].apply(null, args);
                }
                //回调函数执行完，必须删除引用?等下次访问时重置?
                //delete widget.global.callBackStack[tarWidget.getWidgetName()];
                //处理下一个节点
                widget._toNextTarget(assistName, nextTar, tarWidget);
                return;
            }
            //正常处理
            var node = widget.getNode(assistName, tarWidget.getWidgetName());
            if(!!node){
                if($.isFunction(node.end)){
                    nextTar = node.end.apply(tarWidget,args);
                }else{
                    nextTar = widget.global.prototypes[assist.prototype].oEnd.apply(tarWidget,args);
                }
                //处理下一个节点
                widget._toNextTarget(assistName, nextTar, tarWidget);
            }
        },
        _assist : function(){
            var tarWidget = arguments[0], nextTar;
            var widget = this, assistName = widget._getAssistName(tarWidget.getElement()), node = widget.getNode(assistName, tarWidget.getWidgetName()), assist = widget._getAssist(assistName);
            if(!!node){
                var args = Array.prototype.slice.call(arguments,1);
                if($.isFunction(node.assist)){
                    //执行配置数据中的方法
                    nextTar = node.assist.apply(tarWidget,args);
                }else{
                    //没有配置相应方法的时候，执行原来基类的方法
                    nextTar = widget.global.prototypes[assist.prototype].oAssist.apply(tarWidget,args);
                }
                //处理下一个节点
                widget._toNextTarget(assistName, nextTar, tarWidget);
            }
        },
        _toNextTarget : function(assistName, nextTar, tarWidget){
            if(!nextTar){
                return false;
            }
            if(!$.isArray(nextTar)){
                nextTar = [nextTar];
            }
            if(nextTar.length > 0){
                var widget = this, tarName = nextTar[0], callBack = nextTar[1];
                if(!$.isArray(tarName)){
                    tarName = [tarName];
                }
                if(tarName.length > 0){
                    if(!vita.self("isString",tarName[0]) || tarName[0] == ""){
                        throw new Error("指向的目标节点名称错误：名称为（" + tarName[0] + "）");
                    }else{
                        if(tarName[tarName.length - 1] == vita.OUT_OF_FOCUS){
                            //离开当前流程，操作权交还上级流程
                            var e = widget._getAssistElement(assistName);
                            if(e && vita.self("isFunction", e.assemble)){
                                switch (tarName.length){
                                    case 1 : e.assemble("end");break;
                                    case 2 : e.assemble("end", tarName[0]);break;
                                    default : e.assemble("end", tarName[0], tarName[1]);break;
                                }
                            }
                        }else{
                            var node = widget.getNode(assistName, tarName[0]);
                            if(node){
                                //参数处理
                                if(vita.self("isObject",tarName[1])){
                                    //第二个值是对象，判定为参数
                                    node.params = tarName[1];
                                }
                                //最后一个参数判断为是否需要刷新
                                if(tarName[tarName.length - 1] == true){
                                    node.refresh = true;
                                }
                                //如果需要回调，则给目标节点设置回调函数
                                if(!$.isArray(callBack)){
                                    callBack = [callBack];
                                }
                                if(callBack.length > 0){
                                    if($.isFunction(callBack[0])){
                                        widget._getAssist(assistName).callBackStack[tarName[0]] = callBack;
                                    }else{
                                        delete widget.global.assists[assistName].callBackStack[tarName[0]];
                                    }
                                }else{
                                    delete widget.global.assists[assistName].callBackStack[tarName[0]];
                                }
                                //创建目标节点
                                if(node.mode == "back-end"){
                                    widget._forBackEnd(assistName, node);
                                }else if(tarName[0].indexOf(":open") > -1){
                                    node._open = true;
                                    widget.turnOn(assistName, node, function(){
                                        delete node._open;
                                    });
                                }else if(tarName[0].indexOf(":menu") > -1){
                                    widget._doMenu(assistName, tarName, callBack, node, tarWidget);
                                }else{
                                    widget.navigate(assistName, node.name);
                                }
                            }
                        }
                    }
                }
            }
        },
        //导航
        navigate : function(assistName, hash){
            //后面可以在这里选择使用hash还是popstate
            vita.router.navigate(assistName + "/" + hash);
        },
        //获取节点
        getNode : function(assistName, nodeName){
            nodeName = nodeName.split(":")[0];
            var node = this._getAssist(assistName).nodes[nodeName];
            if(!node){
                throw new Error("获取节点失败：名称为（" + nodeName + "）");
            }
            return node;
        },
        //激活节点
        activateNode : function(newHash, oldHash){
            if(!newHash){
                //如果锚点为空，返回
                return false;
            }
            var widget = this, newObj = newHash.split("/"), oldObj = oldHash.split("/"),
                element = widget._getAssistElement(newObj[0]), assist, oldNode;
            var assistConf = this._getAssist(newObj[0]);
            var firstNode = assistConf.firstNode;
            if(element.children().length == 0 && newObj[1] != firstNode.name){
                //如果没有任何节点，且请求的不是第一个节点，则初始化第一个节点
                widget.navigate(newObj[0], firstNode.name);
            }else{
                assist = element.children("[data-assist="+newObj[1]+"]");
                oldNode = oldHash ? widget.getNode(oldObj[0], oldObj[1]) : null;
                //一般节点切换的回调
                var callback = function () {
                    if(oldNode){
                        widget.turnOff(oldObj[0], oldNode);
                    }
                };

                if(oldNode != null && newObj[0] != oldObj[0]){
                    //涉及到流程切换
                    if(widget._isChildrenAssist(oldObj[0], newObj[0])){
                        //新的是旧的的子流程
                        if(vita.router.getPositive() == true){
                            if(oldObj[1] == newObj[0]){
                                //主动切换//只展示新的节点，不能隐藏旧的节点，因为新节点在旧节点里
                                callback = vita.noop;
                            }else {
                                widget.turnOn(oldObj[0], widget.getNode(oldObj[0], newObj[0]), callback);
                                return false;
                            }
                        }else if(vita.router.getPositive() == "back"){
                            //回退键//展示新的节点，隐藏旧节点（父级流程），展示新节点在父级流程里的节点
                            callback = function () {
                                widget.turnOn(oldObj[0], widget.getNode(oldObj[0], newObj[0]), function () {
                                    if(oldNode){
                                        widget.turnOff(oldObj[0], oldNode);
                                    }
                                });
                            };
                        }else if(vita.router.getPositive() == "forward"){
                            //前进键//只展示新的节点，不能隐藏旧的节点，因为新节点在旧节点里
                            widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]));
                            return false;
                        }
                    }else if(widget._isChildrenAssist(newObj[0], oldObj[0])){
                        callback = function () {
                            //widget.turnOff(oldObj[0], oldNode);//貌似可以不用隐藏旧节点，只要隐藏流程即可//TODO
                            if(newObj[1] != oldObj[0]){
                                widget.turnOff(newObj[0], widget.getNode(newObj[0], oldObj[0]));
                            }
                        };
                        //旧的是新的的子流程：展示新的节点，隐藏旧的节点
                        if(vita.router.getPositive() == "back"){
                            //回退键//当前回退到父级流程节点，还要再回退一次
                            widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]), callback);
                            return "back";
                        }
                    }else{
                        //没有直接关系：暂时先这样//TODO
                        //新节点所在流程的节点，如果是隐藏的，需要展示；旧节点所在流程的节点，如果是显示的，需要隐藏
                        //暂不知道能不能通用，或者有其他意外影响
                        var nNode = widget._getAssistElement(newObj[0]), oNode = widget._getAssistElement(oldObj[0]), parentAssistName;
                        if(nNode){
                            nNode = nNode.parent();
                            if(nNode.is("[data-assist="+newObj[0]+"]") && nNode.is(":hidden")){
                                parentAssistName = nNode.attr("data-adhere");
                                widget.turnOn(parentAssistName, widget.getNode(parentAssistName, newObj[0]));
                            }
                        }
                        if(oNode){
                            oNode = oNode.parent();
                            if(oNode.is("[data-assist="+oldObj[0]+"]") && oNode.is(":visible")){
                                parentAssistName = oNode.attr("data-adhere");
                                widget.turnOff(parentAssistName, widget.getNode(parentAssistName, oldObj[0]));
                            }
                        }
                    }
                }else if(oldNode != null && newObj[0] == oldObj[0]){
                    //在同一个流程里
                    var newNode = widget.getNode(newObj[0], newObj[1]);
                    var oN = widget._getNodeElement(oldObj[0], oldObj[1]);
                    if(newNode._container && oN && oN.find(newNode._container).length > 0){
                        callback = $.noop;
                    }
                }
                if(vita.router.getPositive() == "forward"){
                    if(widget._isChildrenAssist(newObj[0], newObj[1])){
                        widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]), callback);
                        return "forward";
                    }
                }

                if(vita.router.getPositive() != true && oldNode && oldNode.onSwitch){
                    var tar = element.children("[data-assist="+oldNode.name+"]").find("[data-widget="+oldNode.name+"]");
                    var wId = tar.attr("data-vid");
                    var w = vita.widget.self("getInstance", oldNode.name, wId);//这个方法，禁止开发人员调用
                    if($.isFunction(oldNode.onSwitch.condition)){
                        //如果不是应用触发，并且设置了切换事件，并且设置了切换条件
                        var doReturn = false;
                        oldNode.onSwitch.condition.call(w, function(result){
                            if(result){
                                //符合执行切换事件的条件
                                if($.isFunction(oldNode.onSwitch.event)){
                                    oldNode.onSwitch.event.call(w);
                                }
                                widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]), function(){
                                    widget.turnOff(oldObj[0], oldNode);
                                });
                            }else{
                                //还原
                                widget.navigate(oldObj[0], oldObj[1]);
                                doReturn = true;
                            }
                        });
                        if(doReturn){
                            return vita.REDIRECT;
                        }
                    }else{
                        //没有设置切换条件，默认执行切换事件
                        widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]), function(){
                            if(oldNode){
                                widget.turnOff(oldObj[0], oldNode, function(){
                                    if($.isFunction(oldNode.onSwitch.event)){
                                        oldNode.onSwitch.event.call(w);
                                    }
                                });
                            }
                        });
                    }
                }else{
                    //忽略切换事件
                    widget.turnOn(newObj[0], widget.getNode(newObj[0], newObj[1]), callback);
                }
            }
        },
        //打开节点
        turnOn : function(assistName, node, callBack){
            var widget = this, element = widget._getAssistElement(assistName), url = node.url,
                callBack = $.isFunction(callBack) ? callBack : $.noop, assistConf = widget._getAssist(assistName);
            //使用open方式打开
            if(node._open == true){
                var open = window[assistConf.openMethod];
                if($.isFunction(open)){
                    open(widget._addParams(node.url, widget._dealParams(node.params)));
                    callBack.call(widget);
                }
                return false;
            }
            //一般处理
            var container = element;
            if(node._container){
                container = node._container;
            }
            var div = container.find("[data-assist="+node.name+"][data-adhere="+assistName+"]");
            if(div.length == 0){
                div = widget._newNodeElement(assistName, node.name).appendTo(container);
            }
            if(div.html() == "" || node.refresh){
                //当容器里没有内容，或者强制刷新时，加载界面
                if(typeof node.params != "object"){
                    node.params = {};
                }else{
                    widget._dealParams(node.params);
                }
                node.params.inFrame = true;
                //销毁节点
                var childIsAssemble = div.children("[data-widget=assemble]"), destroyWidgets = true;
                if(childIsAssemble.length > 0){
                    var childAssistName = childIsAssemble.attr("data-assistname");
                    var childAssist = widget._getAssist(childAssistName);
                    //debugger;
                    if(childAssist.plural){
                        destroyWidgets = false;
                    }
                }
                if(destroyWidgets){
                    var inWidgets = div.find("[data-vid]");
                    inWidgets.each(function(i, w){
                        var ww = $(w), name = ww.attr("data-widgetfullname").split("-")[1];
                        if($.isFunction(ww[name])){
                            ww[name]("destroy");
                        }
                    });
                }else{
                    div.children().detach();
                }
                var options = {
                    mask : assistConf.mask, timeout : assistConf.timeout
                }, headers = typeof node.headers === "undefined" ? assistConf.headers : node.headers;
                switch (vita.type(headers)){
                    case "object" :
                        options.headers = headers;
                        break;
                    case "function" :
                        options.headers = headers();
                        break;
                }
                vita.load(div, url, node.params, function(){
                    delete node.params;
                    delete node.refresh;
                    delete node._container;
                    div.show();
                    callBack.call(widget);
                }, options);
            }else{
                div.show();
                callBack.call(widget);
            }
        },
        //关闭节点
        turnOff : function(assistName, node, callBack){
            this._getNodeElement(assistName, node.name).hide();
            if($.isFunction(callBack)){
                callBack.call(this);
            }
        },
        //处理菜单
        _doMenu : function(assistName, tarName, callBack, node, tarWidget){
            var start = tarName[0].indexOf("(");
            if(start == -1 && $.isFunction(callBack[0])){
                //没送容器id，将url返回
                if(vita.self("isObject", callBack[1])){
                    callBack[0].call(callBack[1], node.url);
                }else{
                    callBack[0](node.url);
                }
            }else{
                //送了id，找容器加载
                var tt;
                var id = tarName[0].substring(start + 1, tarName[0].length - 1);
                if(id.indexOf(".") > 0){
                    var assist = this._getAssistElement(assistName);
                    tt = assist.find("[data-assist="+id.split(".")[0]+"]");
                    id = id.split(".")[1];
                }else {
                    tt = tarWidget.getElement();
                }
                var div = tt.find("#"+id);
                node._container = div;
                this.navigate(assistName, node.name);
            }
        },
        //增加参数
        _addParams : function (url, params) {
            if(params){
                url = url.indexOf("?") > -1 ? url + "&" : url + "?";
                for(var p in params){
                    url += p + "=" + params[p] + "&";
                }
            }
            return url;
        },
        _dealParams : function (obj) {
            for(var key in obj){
                var value = obj[key];
                if(typeof value !== "string"){
                    obj[key] = JSON.stringify(value);
                }
            }
            return obj;
        }
    });

})(window.vita, window.location, window);
(function(vita){
    /**
     * params :
     * 1、obj : 移动过程中显示的html对象
     * 2、start : 移动开始位置
     * 3、end : 移动结束位置
     * 4、processes : 动画过程，可以是对象，也可以是数组，按数组顺序执行
     * {
     *      left :
     *      top :
     *      opacity :
     *      time : 500
     *      callBack : function(){}
     * }
     */
    vita.widget("moveTo", {
        global : {
            time : 500
        },
        _checkParams : function(obj, start, end){
            if(!obj){
                return "没有指定可移动的对象";
            }
            if(!start || !(start.top && start.left)){
                return "没有指定可移动的对象的起始位置";
            }
            if(!end || !(end.top && end.left)){
                return "没有指定可移动的对象的结束位置";
            }
            return true;
        },
        trigger : function(obj, start, end, processes){
            //有动画在执行时，终止
            if($(":animated").length > 0){
                return false;
            }
            //校验参数
            var checkRe = this._checkParams(obj, start, end);
            if(checkRe != true){
                console.error(checkRe);
                return false;
            }
            //转为jquery对象
            if(!vita.self("isJQueryObj", obj)){
                obj = $(obj);
            }
            //执行
            var oPosition = obj.css("position"), oZIndex = obj.css("z-index");
            obj.css({"position":"absolute", "z-index":"9999", "left" : start.left, "top" : start.top});
            var animates = [], global = this.global;
            if(processes){
                if(!vita.self("isArray", processes)){
                    processes = [processes];
                }
                animates = processes;
            }
            animates.push(end);

            var doAnimate = function(){
                if(animates.length > 0){
                    var end = animates.shift(), p = {};
                    if(end.top){
                        p.top = end.top;
                    }
                    if(end.left){
                        p.left = end.left;
                    }
                    if(end.opacity){
                        p.opacity = end.opacity;
                    }
                    obj.animate(p, end.time ? end.time : global.time, function(){
                        if(vita.self("isFunction", end.callBack)){
                            end.callBack();
                        }
                        doAnimate();
                    });
                }else{
                    obj.css({"position":oPosition, "z-index":oZIndex});
                }
            };

            doAnimate();
        }
    });
})(window.vita);
/**
 * @author yangyj
 * @desc htmlTag.js html标签处理
 * @depends core.js
 * @description
 * 1 、 vita-data 用来缓存数据，for属性指定数据缓存的目标，值为id，如果不指定for属性，则将其前一个节点作为缓存目标，如果vita-data是第一个节点，则将父节点作为缓存的目标；标签内的内容为需要缓存的数据，如果是简单字符串，缓存的key为vita-data，如果是json，则按照json的key和value
 * 2 、 vita-bind 数据绑定，for属性同上，action属性指定
 */
(function (vita) {
    vita.widget("htmlTag", {
        init : function (range) {
            //获取检索范围
            range = htmlTag.getRange(range);
            //处理数据附加
            this._data(range);
            //处理数据绑定
            this._bind(range);
        },
        //数据附加
        data : function (range, elementCheckFun) {
            this._data(htmlTag.getRange(range), elementCheckFun);
        },
        _data : function (range, elementCheckFun) {
            var elements = range.find("vita-data,.vita-data");
            elements.each(function (index, element) {
                var tag = $(element), tar = htmlTag.getTarget(tag, range), value = tag.html();
                if(vita.self("isFunction", elementCheckFun)){
                    if(!elementCheckFun(tar)){
                        return true;
                    }
                }
                if(value && typeof value === "string"){
                    value = $.trim(value);
                    if(htmlTag.isJson(value)){
                        //判断为json
                        tar.data(JSON.parse(value));
                    }else{
                        //设置默认key
                        tar.data("vita-data", value);
                    }
                }
                tag.remove();
            });
        },
        //数据绑定
        bind : function (range, modelSetFun, modelBindFun, elementCheckFun) {
            this._bind(htmlTag.getRange(range), modelSetFun, modelBindFun, elementCheckFun);
        },
        _bind : function (range, modelSetFun, modelBindFun, elementCheckFun) {
            range = htmlTag.getRange(range);
            var elements = range.find("vita-bind,.vita-bind");
            elements.each(function (iElement, element) {
                var tag = $(element), tar = htmlTag.getTarget(tag, range),
                    action = tag.attr("action"), mapper = tag.attr("mapper"), model = tag.attr("model"), defaultValue = tag.html();
                if(vita.self("isFunction", elementCheckFun)){
                    if(!elementCheckFun(tar)){
                        return true;
                    }
                }
                if(!model){
                    //没有指定model，返回
                    return true;
                }else{
                    model = model.split(",");
                }
                //没有指定mapper，如果是input，则默认为取value，如果不是input，则默认取html
                mapper = mapper ? mapper.split(",") : htmlTag.isInput(tar) ? ["value"] : ["html"];
                //默认值处理
                if(defaultValue){
                    if(htmlTag.isJson(defaultValue)){
                        defaultValue = JSON.parse(defaultValue);
                    }else{
                        var tObj = {};
                        $.each(mapper, function (iMap, map) {
                            tObj[map] = defaultValue;
                        });
                        defaultValue = tObj;
                    }
                    $.each(mapper, function (iMapper, m) {
                        var value = defaultValue[m] ? defaultValue[m] : null;
                        if(m == "html"){
                            tar.html(value);
                        }else if(m == "value"){
                            tar.val(value);
                        }else {
                            tar.attr(m, value);
                        }
                        vita.self("isFunction", modelSetFun) && modelSetFun(model[iMapper], value);
                    });
                }
                //动作处理
                if(!htmlTag.isInput(tar)){
                    action = null;
                }else {
                    action = action ? action.split(",") : $.support.input ? ["input"] : ["propertychange"];
                }
                var isTrigger = true;
                if(action &&　vita.self("isFunction", modelSetFun)) {
                    //存在指定的model set事件
                    $.each(action, function (iAction, a) {
                        tar.bind(a, function () {
                            isTrigger = false;
                            $.each(mapper, function (i, m) {
                                var value;
                                if(m == "html"){
                                    value = tar.html();
                                }else if(m == "value"){
                                    value = tar.val();
                                }else{
                                    value = tar.attr(m);
                                }
                                modelSetFun(model[i], value);
                            });
                        });
                    });
                }
                if(vita.self("isFunction", modelBindFun)){
                    $.each(mapper, function (i, m) {
                        modelBindFun(model[i], function (value) {
                            var aa = m;
                            if(isTrigger){
                                if(aa == "html"){
                                    tar.html(value);
                                }else if(aa == "value"){
                                    tar.val(value);
                                }else{
                                    tar.attr(m, value);
                                }
                            }
                            isTrigger = true;
                        });
                    });
                }
                tag.remove();
            });
        }
    });

    var htmlTag = {
        //获取检索范围，返回jquery对象
        getRange : function (range) {
            if(!range){
                range = $("body");
            }else if(!vita.self("isJQueryObj", range)){
                range = $(range);
            }
            return range;
        },
        //判断内容是否json
        isJson : function (value) {
            return !!value && value.charAt(0) == "{" && value.charAt(value.length - 1) == "}";
        },
        //获取发生作用的对象
        getTarget : function (tag, source) {
            var tar, tarId = tag.attr("for");
            if(!tarId){
                if(tag.prev().length > 0){
                    tar = tag.prev();
                }else {
                    tar = tag.parent();
                }
            }else{
                tar = source.find("#" + tarId);
            }
            return tar;
        },
        isInput : function (element) {
            if(element.is(":input")){
                return true;
            }else{
                return false;
            }
        }
    };

    //让IE8兼容自定义标签
    if(!$.support.input){
        document.createElement("vita-data");
        document.createElement("vita-bind");
    }
    //隐藏自定义标签
    var head = document.getElementsByTagName("head")[0];
    var style = document.createElement("style"), template = "vita-data,.vita-data,vita-bind,.vita-bind{display:none}";
    if ("styleSheet" in style) {
        style.setAttribute("type", "text/css");
        style.styleSheet.cssText = template;
    }else{
        style.innerHTML = template;
    }
    head.appendChild(style);
})(window.vita);